/*************************************************************************//**
 *****************************************************************************
 * @file   include/sys/fs.h
 * @brief  Header file for File System.
 * @author Forrest Yu
 * @date   2008
 *****************************************************************************
 *****************************************************************************/

#ifndef	_ORANGES_FS_H_
#define	_ORANGES_FS_H_

/**
 * @struct dev_drv_map fs.h "include/sys/fs.h"
 * @brief  The Device_nr.\ - Driver_nr.\ MAP.
 */
struct dev_drv_map {
	int driver_nr; /**< 设备驱动程序的 proc nr.\。 */
};

/**
 * @def   MAGIC_V1
 * @brief Magic number of FS v1.0
 */
#define	MAGIC_V1	0x111

/**
  * @struct super_block fs.h "include/fs.h"
  * @brief FS 的第二个扇区
  *
  * 如果成员更改，请记住更改 SUPER_BLOCK_SIZE。
  */
struct super_block {
	u32	magic;		      // 文件系统标识符                 /**< Magic number */
	u32	nr_inodes;	      // 文件系统最多允许多少个 i-none  /**< How many inodes */
	u32	nr_sects;	      // inode_array 占用多少扇区       /**< How many sectors */
	u32	nr_imap_sects;	  // inode-map 占用多少扇区         /**< How many inode-map sectors */
	u32	nr_smap_sects;	  // sector-map 占用多少扇区        /**< How many sector-map sectors */
	u32	n_1st_sect;	      // 第一个数据扇区的扇区号是多少   /**< Number of the 1st data sector */
	u32	nr_inode_sects;   /**< How many inode sectors */
	u32	root_inode;       // 根目录区的 i-node 号是多少     /**< Inode nr of root directory */
	u32	inode_size;       /**< INODE_SIZE */
	u32	inode_isize_off;  /**< Offset of `struct inode::i_size' */
	u32	inode_start_off;  /**< Offset of `struct inode::i_start_sect' */
	u32	dir_ent_size;     /**< DIR_ENTRY_SIZE */
	u32	dir_ent_inode_off;/**< Offset of `struct dir_entry::inode_nr' */
	u32	dir_ent_fname_off;/**< Offset of `struct dir_entry::name' */

	/*
	 * 以下项目仅存在于内存中
	 */
	int	sb_dev; 	/**< the super block's home device */ // (/**< 超级块的家庭设备 */)
};

/**
 * @def   SUPER_BLOCK_SIZE
 * @brief The size of super block \b in \b the \b device.
 *
 * 请注意，这是设备中结构的大小，\b 不在内存中。
  由于更多的成员，内存中的大小更大。
 */
#define	SUPER_BLOCK_SIZE	56

/**
 * @struct inode
 * @brief  i-node
 *
 * \c start_sect 和\c nr_sects 定位设备中的文件，大小显示使用了多少字节。
 * 如果 <tt> size < (nr_sects * SECTOR_SIZE) </tt>，则剩余字节被浪费并保留供以后写入。
 * \b 注意：如果成员更改，请记住更改 INODE_SIZE
 */
struct inode {
	u32 i_mode;        // 文件类型          /**< 访问模式 */
	u32 i_size;        // 文件大小
	u32 i_start_sect;  // 文件的起始扇区    /**< 数据的第一个扇区 */
	u32 i_nr_sects;    // 总扇区数          /**< 文件占用多少扇区 */
	u8  _unused[16];   /**< 对齐的东西 */

	/* 以下项目仅存在于内存中 */
	int i_dev;
	int i_cnt; /**< 有多少 proc 共享这个 inode */
	int i_num; /**< 索引节点编号。 */
};

/**
  * @def INODE_SIZE
  * @brief 存储在 \b 设备中的 i-node 的大小。
  *
  * 请注意，这是设备中结构的大小，\b 不在内存中。
  * 由于成员较多，内存中的大小较大。
  */
#define	INODE_SIZE	32

/**
 * @def   MAX_FILENAME_LEN
 * @brief Max len of a filename
 * @see   dir_entry
 */
#define	MAX_FILENAME_LEN	12

/**
 * @struct dir_entry
 * @brief  Directory Entry
 *
 * 它是存在于根目录文件中的数据结构，用来索引一个文件。
 * 将来我们的根目录将会是一个 dir_entry 数组，用以 索引 文件系统中所有文件。
 */
struct dir_entry {
	int	inode_nr;		/**< inode nr. */
	char	name[MAX_FILENAME_LEN];	 // 文件名
};

/**
  * @def DIR_ENTRY_SIZE
  * @brief 设备中目录条目的大小。
  *
  * 它与内存中的大小相同。
  */
#define	DIR_ENTRY_SIZE	sizeof(struct dir_entry)


// File Descript
struct file_desc {
    int fd_mode; // 读或写
    int fd_pos;  // 记录读写到了文件的哪个位置
    struct inode* fd_inode; // inode 的指针, 即具体文件的位置
};
	

/**
  * 由于 FS 中所有 `rw_sector()' 的调用看起来都相似（大多数
  * 参数相同），我们使用这个宏来使代码更具可读性。
  */
#define RD_SECT(dev,sect_nr) rw_sector(DEV_READ, \
				       dev,				\
				       (sect_nr) * SECTOR_SIZE,		\
				       SECTOR_SIZE, /* read one sector */ \
				       TASK_FS,				\
				       fsbuf);
#define WR_SECT(dev,sect_nr) rw_sector(DEV_WRITE, \
				       dev,				\
				       (sect_nr) * SECTOR_SIZE,		\
				       SECTOR_SIZE, /* write one sector */ \
				       TASK_FS,				\
				       fsbuf);

#endif /* _ORANGES_FS_H_ */
